package com.k8sops.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.k8sops.backend.common.BusinessException;
import com.k8sops.backend.entity.Cluster;
import com.k8sops.backend.mapper.ClusterMapper;
import com.k8sops.backend.service.ClusterService;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.util.Config;
import io.kubernetes.client.util.KubeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.List;

@Slf4j
@Service
public class ClusterServiceImpl extends ServiceImpl<ClusterMapper, Cluster> implements ClusterService {

    @Override
    public List<Cluster> listClusters() {
        LambdaQueryWrapper<Cluster> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Cluster::getDeleted, 0);
        wrapper.orderByDesc(Cluster::getCreateTime);
        return list(wrapper);
    }

    @Override
    public boolean addCluster(Cluster cluster) {
        // 验证集群连接是否有效
        try {
            testClusterConnection(cluster.getKubeConfig());
        } catch (Exception e) {
            log.error("集群连接测试失败", e);
            throw new BusinessException("集群连接测试失败：" + e.getMessage());
        }
        
        cluster.setStatus(1); // 设置为在线状态
        cluster.setCreateTime(LocalDateTime.now());
        cluster.setUpdateTime(LocalDateTime.now());
        cluster.setDeleted(0);
        return save(cluster);
    }

    @Override
    public boolean updateCluster(Cluster cluster) {
        Cluster existCluster = getById(cluster.getId());
        if (existCluster == null) {
            throw new BusinessException("集群不存在");
        }
        
        // 如果修改了kubeConfig，需要验证连接是否有效
        if (!existCluster.getKubeConfig().equals(cluster.getKubeConfig())) {
            try {
                testClusterConnection(cluster.getKubeConfig());
            } catch (Exception e) {
                log.error("集群连接测试失败", e);
                throw new BusinessException("集群连接测试失败：" + e.getMessage());
            }
        }
        
        cluster.setUpdateTime(LocalDateTime.now());
        return updateById(cluster);
    }

    @Override
    public boolean deleteCluster(Long id) {
        Cluster cluster = getById(id);
        if (cluster == null) {
            throw new BusinessException("集群不存在");
        }
        
        // 逻辑删除
        cluster.setDeleted(1);
        cluster.setUpdateTime(LocalDateTime.now());
        return updateById(cluster);
    }

    @Override
    public boolean testConnection(Long id) {
        Cluster cluster = getById(id);
        if (cluster == null) {
            throw new BusinessException("集群不存在");
        }
        
        try {
            testClusterConnection(cluster.getKubeConfig());
            // 更新集群状态为在线
            cluster.setStatus(1);
            cluster.setUpdateTime(LocalDateTime.now());
            updateById(cluster);
            return true;
        } catch (Exception e) {
            log.error("集群连接测试失败", e);
            // 更新集群状态为离线
            cluster.setStatus(0);
            cluster.setUpdateTime(LocalDateTime.now());
            updateById(cluster);
            return false;
        }
    }
    
    /**
     * 测试集群连接
     * @param kubeConfig 集群配置
     * @throws IOException IO异常
     * @throws ApiException API异常
     */
    private void testClusterConnection(String kubeConfig) throws IOException, ApiException {
        // 解码Base64编码的kubeConfig
        byte[] decodedBytes = Base64.getDecoder().decode(kubeConfig);
        String decodedConfig = new String(decodedBytes, StandardCharsets.UTF_8);
        
        // 使用KubeConfig加载配置
        KubeConfig config = KubeConfig.loadKubeConfig(new InputStreamReader(
                new ByteArrayInputStream(decodedConfig.getBytes(StandardCharsets.UTF_8))));
        ApiClient client = Config.fromConfig(config);
        
        // 设置较短的超时时间
        client.setConnectTimeout(5000);
        client.setReadTimeout(5000);
        
        // 测试连接，尝试获取命名空间列表
        CoreV1Api api = new CoreV1Api(client);
        api.listNamespace(null, null, null, null, null, null, null, null, null, null);
    }
}
